package juego;

import java.util.ArrayList;
import java.util.Iterator;
import vista.VistaTripulado;

import ar.uba.fi.algo3.titiritero.Dibujable;



public class Tripulado extends Movil {

	
	//atributos de clase
	private static int miOrigenEnX = 170;
	private static int miOrigenEnY = 350;
	private static int miResistenciaMaxima = 30;
	private static int miTamanio = 5;
	private static int miVelocidad = 10;//15;
	private static int miImpacto = 10;
	private static int miCapacidadArmamento = 3;
	
	//atributos de instancia
	private Energia resistencia;
	private Disparable armamento[]; 	
	private int cantidadArmas;
	//metodos
	
	//constructor. siempre tiene la misma ubicacion inicial
	public Tripulado() {
		super (miOrigenEnX, miOrigenEnY);
		this.resistencia = new Energia (miResistenciaMaxima);
		this.armamento = new Disparable[miCapacidadArmamento];
		this.armamento[0] = new ArmaLaser();
		this.cantidadArmas = 1;
	};
	
	//Devuelve el impacto provocado
    @Override
	public Impacto impactoProvocado(){
		return new ImpactoLineal(miImpacto);
	};   

	@Override
	public boolean esNaveEnemiga() {
		return false;
	};

	@Override
	public boolean esProyectil() {
		return false;
	};

	@Override
	public boolean verLealtad(){
		return true;
	};
	
	@Override
	public int verTamanio(){
		return miTamanio;
	};

	public void recargarEnergia(int mejora) {
		this.resistencia.incrementarEnergia(mejora);
	};
	
	//crea una nueva ArmaCohete y ArmaTorpedoRastreador
	//y los posiciona donde estaban los mismos previamente. 
	public void recargarArmamento(){
		this.armamento[1] = new ArmaCohete();
		this.armamento[2] = new ArmaTorpedoRastreador();
		this.cantidadArmas = 3;
	}
	
	public int verResistencia(){
		return this.resistencia.verEnergia();
	};
	
	//pre: recibe como parametros las listas de moviles y de botines.
	//post: actualiza las listas y retorna los puntos que deban computarse.
	//si no esta vivo lanza una excepcionMuerto
	@Override
	public int vivir(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		if (!this.vivo){
			throw new ExcepcionMuerto();
		}
		//impacto
		int puntaje = this.impactar(listaDeMoviles,listaDeBotines);
		this.recuperarBotin(listaDeBotines);
		return puntaje;
	};
	
	//resuelve el choque. retorna el puntaje
	protected int impactoPropio(Movil movil, ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		int puntaje = 0;
		//solo puede impactar moviles enemigos
		if (!movil.verLealtad()){
			//movil hiere a this
			movil.impactoProvocado().herir(this.resistencia);
			//movil recibe el impacto. se elimina de la lista si corresponde.se modifica el puntaje
			puntaje += movil.recibirImpacto(this.impactoProvocado(), listaDeMoviles, listaDeBotines);
		}
		return puntaje;
	}
	
	//se encarga de destruirse si corresponde. devuelve el puntaje
	protected int verificarDestruccion(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		//si queda energia no se destruye y retorna 0
		if(this.resistencia.quedaEnergia()){
			return 0;
		}
		//si se destruye retorna 0
		this.destruirse(listaDeMoviles);
		return 0;
	}
	
	
	//se encarga de recorrer la lista de botines y utilizar los que encuentre
	private void recuperarBotin(ArrayList<Botin> listaDeBotines) {
		Iterator<Botin> iterador = listaDeBotines.iterator();
		while (iterador.hasNext()){
			Botin botin = iterador.next();
			try{
				if (botin.huboContacto(this)){
					botin.mejorar(this);
					iterador.remove();
				}
			}
			catch (ExcepcionMismoElemento e){};
		}
	};
				
				

	
//	
//	//Retorna el puntaje acumulado por la destruccion de otros moviles.
//	//Este metodo se encarga de llamar al metodo destruirse.
//	@Override
//	protected int impactar(ArrayList<Movil> listaDeMoviles, 
//			ArrayList<Botin> listaDeBotines){
//		
//		int puntaje = 0;
//		Iterator<Movil> iterador = listaDeMoviles.iterator();
//		boolean contacto;
//				
//		while (iterador.hasNext()){
//			
//			Movil movil = iterador.next();
//			try {
//				contacto = movil.huboContacto(this);
//				
//				if (contacto & !movil.verLealtad()){
//					
//					//recibe el impacto
//					movil.impactoProvocado().herir(this.resistencia);
//										
//					//provoca el impacto
//					puntaje += movil.recibirImpacto(this.impactoProvocado(), listaDeMoviles, listaDeBotines);
//					
//					//si no esta vivo lo elimina de la lista
//					if (!movil.estaVivo()){
//						iterador.remove();
//					};
//				}
//			}
//			catch (ExcepcionMismoElemento e){}
//		}
//		
//		if (!this.resistencia.quedaEnergia()){
//			this.destruirse(listaDeMoviles);
//		}
//		
//		return puntaje;
//	};
	
		
//	@Override
//	public int recibirImpacto(Impacto danio, ArrayList<Movil> listaDeMoviles,
//			ArrayList<Botin> listaDeBotines){
//		
//		danio.herir(this.resistencia);
//		
//		if (!resistencia.quedaEnergia()){
//			this.vivo = false;
//		};
//		
//		return 0;
//	}
//	
	
	@Override
	//se elimina de la lista si corresponde. devuelve 0
	public int recibirImpacto(Impacto impacto, ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		impacto.herir(this.resistencia);
		int puntaje = this.verificarDestruccion(listaDeMoviles, listaDeBotines);
		return puntaje;
	}
	
	
	//si esta muerto lanzan una excepcionMuerto
	
	public void moverEnXPositivo(){
		if (!this.vivo){
			throw new ExcepcionMuerto();
		}
        this.ubicacion.moverEnX(miVelocidad);
	}
	
	public void moverEnXNegativo(){
		if (!this.vivo){
			throw new ExcepcionMuerto();
		}
        this.ubicacion.moverEnX(-miVelocidad);
	}

	public void moverEnYNegativo(){
		if (!this.vivo){
			throw new ExcepcionMuerto();
		}
        this.ubicacion.moverEnY(-miVelocidad);
	}
	
	public void moverEnYPositivo(){
		if (!this.vivo){
			throw new ExcepcionMuerto();
		}
        this.ubicacion.moverEnY(miVelocidad);
	}
	
	public void disparar(ArrayList<Movil> listaDeMoviles){
		if (!this.vivo){
			throw new ExcepcionMuerto();
		}
		int lugarDisparo = 0;
		Coordenada lugar;
		int lugarX = this.ubicacion.obtenerCoordenadaX();
		int lugarY = this.ubicacion.obtenerCoordenadaY();
		int indice = 0;
		while (indice < this.cantidadArmas){
			try{
				lugar = new Coordenada(lugarX + lugarDisparo, lugarY);
				Proyectil proyectil = this.armamento[indice].disparar(lugar);
				proyectil.hacerLeal();
				listaDeMoviles.add(proyectil);
				lugarDisparo++;
			}
			catch(ExcepcionMunicionAgotada e){}
			indice++;
		}
	}
	
	@Override
	public Dibujable getDibujable() {
		Dibujable dibujable = new VistaTripulado();
		dibujable.setPosicionable(this);
		return dibujable;
	};

	
	

	

}
